home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ansi
/
zeno25.zip
/
ZENO.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-01-19
|
14KB
|
421 lines
Page 60,132
; ZENO: June 11, 1986 «RM120»«IP0,6»
; Modified Sept 4, 1986 by R Tansky to fix 40-character mode
; Modified Oct 31, 1986 by R Tansky to further fix 40-character mode and to
; fix graphics mode
; Modified Jan 28, 1987 by C Blum to add code to support TTY mode call
; (AH=0Eh). Required by some clone BIOS implementations (DTK/ERSO for
; one) because they do not issue any 'set cursor' calls from within the
; TTY mode call. This causes ZENO to lose its video offset and the
; display goes out to lunch.
; Modified May 29, 1987 by Lynn Ransdell to support KEDIT 3.51
; Modified Dec 13, 1988 by Glenn K. Smith to do snow suppression and to add
; a /S option to enable this suppression. Use of this switch causes
; ZENO to be around 2 1/2 times slower (ZENOTEST=66 @10mhz).
; Modified Jan 15, 1988 by Glenn K. Smith to speed up snow checking and to
; fix a bug. Some programs didn't work right with ZENO. Mainly those
; which modified the cursor position without calling ZENO (Procomm+,
; Turbo Pascal CRT unit and others). The fix required calculating the
; screen offset using the BIOS cursor everytime a character was placed
; on the screen. ZENOTEST now takes 46 seconds @10mhz instead of 66.]
; Modified Jan 19, 1989 by Howard Flank to work correctly with AMI 386 BIOS.
; Rewrote the command line scanner, accepts upper/lower, switches may be
; preceeded by slash, dash, or space, etc. Changed the /K switch to the
; more standard /U switch. Put cursor recalc code for ERSO BIOS on /E
; switch. Added /H switch to display a help screen. 'Prettied' up the
; messages. Made redundant code into subroutines. Changed 'kill' code
; for compatibility with TopView and moved 'kill' message out of resident
; code. Resident code is 200 bytes smaller.
cseg segment para public 'code'
zeno proc far
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
org 100h ; for .COM file
;------------------------------*
; ENTER HERE ON INITIAL LOAD *
;------------------------------*
start: jmp near ptr load_pgm
CR equ 0Dh
LF equ 0Ah
video_vector dd 0
core_seg dw 0
bios_cursor_pos label dword
bios_ofst dw 00h ; offset for active page
dw 40h ; segment for bios data
crt_mode db 2 ; passes if 4, 5, or 6
active_page db 0
cursor_type dw 0B0Ch ; DOS cursor
video_posn label dword
video_ofst dw 0 ; offset against video_seg
video_seg dw 0
video_addr dw 0
onesixty db 160
snow db 0 ; Snow suppression flag
recalc db 0
;---------------------------*
; ENTER HERE FROM INT 10H *
;---------------------------*
video_int: sti ; interrupts on
pushf ; save flags
cmp cs:crt_mode,3 ; check for color text 1
je video_keep ; go if so
cmp cs:crt_mode,2 ; check for color text 2
je video_keep ; go if so
cmp cs:crt_mode,7 ; check for b/w
je video_keep ; go if so
cmp ah,0 ; check for set mode
je video_keep ; if so, continue
jmp short video_rtn ; go if graphics / 40 col
video_keep: push ds ; save regs
push es
push di
push ax
push cx
push dx
push cs ; set ds for addressibility
pop ds
cmp recalc,3 ; ERSO cursor recalc req'd?
jne video_func ; no:
les di,bios_cursor_pos ; yes: recalc
push ax
push cx
mov ax,es:[di]
call calc_offset ; calc offset into video ram
and recalc,0FEh ; clear recalc flag
pop cx
pop ax
video_func: cmp ah,1 ; to set type
je $set_type
cmp ah,0 ; to set mode
je $set_mode
cmp ah,5 ; to set page
je $set_page
cmp ax,0F0F0h ; uninstall code
je $remove ; go if found
cmp bh,active_page ; check if active page
jne video_exit ; no: use BIOS
cmp ah,14 ; to write as TTY
je $TTY
cmp ah,2 ; to set cursor
je set_cursor
cmp ah,3 ; to read cursor
je $read_cursor
cmp cx,1 ; check multiple write
jne video_exit ; yes: use BIOS
cmp ah,10 ; to write char only
je write_char
cmp ah,9 ; to write char/attr
je $write_both
video_exit: pop dx ; restore regs
pop cx
pop ax
pop di
pop es
pop ds
video_rtn: popf ; restore flags
jmp cs:dword ptr video_vector ; hand off interrupt to BIOS
$TTY: jmp TTY
$write_both: jmp write_both
$read_cursor: jmp read_cursor
$set_page: jmp set_page
$set_type: jmp set_type
$set_mode: jmp set_mode
$remove: jmp remove
write_char: Call Display1
jmp zeno_exit
set_cursor: add video_ofst,2 ; for next char
les di,bios_cursor_pos ; get bios
inc byte ptr es:[di] ; assume next
cmp es:[di],dx ; check if next
je offset_ready ; go if next
mov ax,dx ; get req posn
mov es:[di],ax ; save req posn
call calc_offset ; calc offset into video ram
offset_ready: mov cx,video_ofst ; offset in cx
shr cx,1 ; for byte count
mov ah,14 ; cursor MSB register
mov dx,video_addr ; 6845 index addr
mov al,ah ; get register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,ch ; get cursor MSB
out dx,al ; send cursor MSB
dec dx ; 6845 index addr
mov al,ah ; cursor MSB register
inc al ; cursor LSB register
out dx,al ; send register
inc dx ; 6845 data addr
mov al,cl ; get cursor LSB
out dx,al ; send cursor LSB
jmp zeno_exit
write_both: mov ah,bl ; get attribute
push ax
les di,bios_cursor_pos
mov ax,es:[di]
Call Calc_Offset
les di,video_posn ; get screen position
cmp snow,1 ; Snow suppression?
je color ; yes:
pop ax
stosw ; Place char+attr onto screen
jmp short zeno_exit
color: mov dx,03DAh
cli
WaitNoH1: in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE1 ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH1 ; horizontial retrace
WaitH1: in al,dx ; Get 6845 status again
rcr al,1 ; Wait for horizontial
jnc WaitH1 ; retrace
WaitE1: pop ax
stosw
sti
zeno_exit: pop dx ; restore regs
pop cx
zeno_exit2: pop ax
pop di
pop es
pop ds
popf ; restore flags
iret ; return from interrupt
set_recalc: or recalc,1 ; set cursor pos recalc, then
$video_exit: jmp video_exit ; use BIOS routines
read_cursor: pop dx ; pop regs off stack
pop cx
les di,bios_cursor_pos ; get bios
mov dx,es:[di] ; get bios cursor posn
mov cx,cursor_type ; get type
jmp short zeno_exit2
set_page: mov active_page,al ; save page
xor ah,ah ; page in ax
shl ax,1 ; for word count
add ax,50h ; offset for page zero
mov bios_ofst,ax ; save offset
jmp video_exit ; pass to bios
set_type: mov cursor_type,cx ; save type
jmp video_exit ; pass to bios
set_mode: mov crt_mode,al ; save mode
mov video_ofst,0 ; top left
jmp video_exit ; done
TTY: cmp al,' ' ; control characters?
jb set_recalc ; yes: set for recalc, use BIOS
cmp video_ofst,25*80*2-2 ; scroll imminent ?
jnb set_recalc ; yes: set for recalc, use BIOS
Call Display1 ; display w/ or w/o snow
les di,bios_cursor_pos ; get bios
mov dx,es:[di] ; get current pos
inc dl ; next char pos
cmp dl,79 ; new line ?
ja TTY_new_line ; yes, adjust
jmp set_cursor ; set cursor
TTY_new_line: mov dl,0 ; col = 1
inc dh ; inc row
jmp set_cursor ; set cursor
;---- SUBROUTINE: DISPLAY A CHAR W/ OR W/O SNOW SUPPRESSION -------------------
Display1 Proc
push ax
les di,bios_cursor_pos
mov ax,es:[di]
Call Calc_Offset
les di,video_posn ; get screen position
cmp snow,1
je SuppressSnow
pop ax
stosb
ret
SuppressSnow: mov dx,03DAh ; Put char, snow suppressed
cli
WaitNoH: in al, dx ; Get 6845 Status
test al,8 ; Check vert retrace
jnz WaitE ; In Progress? go
rcr al,1 ; Wait for end of
jc WaitNoH ; horizontial retrace
WaitH: in al, dx ; Get 6845 status again
rcr al, 1 ; Wait for horizontial
jnc WaitH ; retrace
WaitE: pop ax
stosb
sti
ret
Display1 EndP
;---- SUBROUTINE: CALC THE VIDEO OFFSET FROM THE CURSOR POSITION (In AX) ------
Calc_Offset Proc
mov cx,ax ; copy posn
mov al,ah ; rows in al
mul onesixty